Syntax
Every line (excluding empty ones) in milk is read and evaluated as a single command. A command or piece of text cannot span multiple lines.
String
Enclosed by single quotes '' or double quotes "". Using single quotes allows you to include double quotes in the string and vice versa. To use ' or " within itself you can simply escape the character using a backslash \.
$x = 'This is a "string"'
$y = "This is also a 'string'"
Number
This simply represents a number. A number can start with a minus - or + plus symbol. A number can also only include a single period ..
$x = -5
$y = +4.2
Boolean
Stores true or false. on and off, yes and no also serve as respective variants.
$happy = yes
$sad = false
$night_mode = off
$night_mode = true
Logical operations are evaluated into boolean values.
$happy = 20 > 1
$sad = 50 <= 20 and 60 == 'forty'
Objects
Objects are not supported. Take a look at accessors
Variable
Variables serve as value data storage. They are not limited by value types.
Variables must start with an underscore symbol _ or a small letter [_a-z]. After that they can contain more letters, numbers and underscore: [_a-zA-Z0-9]*. Hyphen - is not allowed within variables
Valid ✅
$my_var2 = true
$_2var = true
Invalid ❌
// Syntax highlighting fails...
$MyVar = true
$2anotherVar = true
$normal-var = true
NB: This is a well considered design choice but is definitely open for revision
Accessors
Accessors serve as a way to read or write values into internal game variables. They may bear the same name as normal variables, but they are treated differently in the engine.
They are represented by variable_name:prop1:prop2
$jo:bra = off
$flora:title = "Flora the great!"
// This creates a separate variable named 'flora'. It will not clash with the accessor above
$flora = "Flora the great!"
Blocks
Comment
This is represented by a single line of text preceded by a double slash //.
// This is a comment
Because milk is structured only in single lines multi-lined comments are not supported.
Text
This is represent by a single line of text. Nothing more, just text.
This is a single line of text
This is another line
Section
Sections serve as reusable blocks (i.e functions)
A section ends with a <-
--- section_1 ---
<-
To call another section simply use -> section_name
-> section_1
Section names follow the same naming convention as a variable
Choice Block
This represents a decision block. When a choice block is used, the game spawns a set of options for the user to select.
Choice block must end with a <-, if not the compiler will simply read every line underneath as more content for the choice block.
* Option 1
// Some text here
* Option 2
// Some more text here
* Option 3
// Final option here
<-
Nesting
Each star * in an choice block represents it's nested level.
* Level 1
// A nested choice block
** Level 2 (inside level one)
** Level 2 - option 2
<-
* Level 1 - option 2
<-
Condition block
This works very similar to a choice block. The key difference is that it uses logical operations (like an if-else statement)
Just like a choice blocks a condition block must end with a <-.
? $happy == true and $sad == false
// Commands here...
? $happy == false
// Condition two
<-
To symbolize else statement i.e what to do if all the above conditions fail,
Simply add a ? without any expressions following it
? $happy == true and $sad == false
// Commands here...
?
// Commands that happen if all else fails
<-
Nesting
Similarly to choice blocks, each ? in represents it's nested level.
? $happy == true and $sad == false
// Level 1 - Condition 1
// A nested condition block
?? 5 > 2
// Level 2 - Condition 1
?? 5 <= 2
// Level 2 - Condition 2
<-
? $happy == false
// Level 1 - Condition 2
<-
Accessors
Accessors work fine within condition blocks
? $flora:happy == true
// Your commands here
<-
Statement
Statements are commands. They get things done within the game. Have a look at the api reference for more information.
Statements work mostly like functions with condition arguments
@statement arg1 arg2:value arg3
@go bedroom
Modifiers
Modifiers follow statements and provide more detailed information
They are denoted by #modifier or #modifier:value.
Values can range from numbers, boolean to string.
#modifier:'some_string'#modifier:1#modifier:true#modifier:off
@show flora #from:left